const jwt = require('jsonwebtoken')
const { JWT_SECRET_KEY } = require('../project.config')
const koaJwt = require('koa-jwt')
const UserModel = require('../models/userModel')

const verify = token => {
    return new Promise((resolve, reject) => {
        jwt.verify(token, JWT_SECRET_KEY, (error, payload) => {
            if (error) {
                reject(error)
            } else {
                resolve(payload)
            }
        })
    })
}

const processToken = ctx => {
    let { authorization } = ctx.header
    return authorization.replace('Bearer ', '').replace('bearer ', '')
}

const middleware = app => {
    app.use(koaJwt({
        secret: JWT_SECRET_KEY,
    }).unless({
        path: [/^\/auth/, /^\/forget-password/], //这些路由不需要token验证
    }))
}

const checker = async (ctx, next) => {
    const { path } = ctx
    if (path.includes('/auth') || path === '/forget-password') {
        await next()
        return
    }

    const { account, roleId, id } = await verify(processToken(ctx))
    const user = await UserModel.findOne({ _id: id })
    if (!user || account !== user.account || roleId !== user.roleId) {
        ctx.status = 401
        ctx.body = {
            code: 0,
            msg: '用户校验失败',
        }
        return
    }
    await next()
}

const catchTokenError = async (ctx, next) => {
    return next().catch(err => {
        //携带token的Authorization参数错误
        if (err.status === 401) {
            ctx.status = 401
            ctx.body = {
                code: 0,
                msg: '未携带token令牌或者token令牌已过期',
                error: err.originalError
                       ? err.originalError.message
                       : err.message,
            }
        } else {
            throw err
        }
    })
}

module.exports = {
    verify,
    processToken,
    middleware,
    catchTokenError,
    checker,
}

